import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import os
import warnings
from scipy.stats import pearsonr
import matplotlib.font_manager as fm

# 忽略警告
warnings.filterwarnings("ignore")

# ====================== 关键修改：手动指定中文字体路径 ======================
# 这里以 Windows 系统的“SimHei”为例，其他系统请替换为对应字体路径
# Windows 字体路径示例：C:/Windows/Fonts/simhei.ttf
# Linux 字体路径示例：/usr/share/fonts/truetype/wqy/wqy-microhei.ttc
# MacOS 字体路径示例：/System/Library/Fonts/PingFang.ttc
font_path = "C:/Windows/Fonts/simhei.ttf"  # 根据你的系统修改
font_prop = fm.FontProperties(fname=font_path)

# 设置全局字体
plt.rcParams["font.family"] = font_prop.get_name()
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

# 创建输出目录
output_dir = 'correlation_analysis'
os.makedirs(output_dir, exist_ok=True)

try:
    # 读取CSV文件
    print("开始读取CSV文件...")
    file_path = 'bilibili_weekly_data.csv'

    # 尝试不同编码
    for encoding in ['gbk', 'utf-8', 'gb18030']:
        try:
            df = pd.read_csv(file_path, encoding=encoding)
            print(f"使用 {encoding} 编码成功读取文件")
            break
        except UnicodeDecodeError:
            print(f"使用 {encoding} 编码失败，尝试下一种编码")

    # 显示基本信息
    print(f"数据总行数: {len(df)}")

    # 处理列名中可能的空格
    df.columns = df.columns.str.strip()

    # 确保数值列为数值类型
    numeric_columns = ['点赞数', '投币数', '收藏数', '评论数', '弹幕数', '转发数', '播放量']
    for col in numeric_columns:
        if col in df.columns:
            df[col] = pd.to_numeric(df[col], errors='coerce')

    # 打印数据基本统计信息
    print("\n数据基本统计信息:")
    print(df[numeric_columns].describe())

    # 1. 计算相关系数矩阵
    print("\n计算相关系数矩阵...")
    correlation_matrix = df[numeric_columns].corr()
    print(correlation_matrix)

    # 2. 绘制相关系数热力图
    print("\n绘制相关系数热力图...")
    plt.figure(figsize=(12, 10))

    # 使用seaborn绘制热力图
    sns.heatmap(
        correlation_matrix,
        annot=True,  # 显示数值
        cmap='coolwarm',  # 使用冷暖色调
        linewidths=0.5,  # 网格线宽度
        fmt='.2f'  # 数值格式
    )

    plt.title('B站视频数据指标相关性热力图', fontproperties=font_prop, fontsize=16)
    plt.tight_layout()

    # 保存图表
    output_file = f"{output_dir}/correlation_heatmap.png"
    plt.savefig(output_file, dpi=300)
    plt.close()
    print(f"已保存热力图: {output_file}")

    # 3. 计算各变量与播放量的相关系数，并按相关性强弱排序
    print("\n计算各变量与播放量的相关系数，并按相关性强弱排序...")
    play_correlations = correlation_matrix['播放量'].sort_values(ascending=False)
    print(play_correlations)

    # 4. 绘制各变量与播放量的相关系数条形图
    print("\n绘制各变量与播放量的相关系数条形图...")
    plt.figure(figsize=(12, 8))

    # 不包括播放量自身
    play_corr_without_self = play_correlations[play_correlations.index != '播放量']

    # 绘制条形图
    colors = ['#66B2FF' if x >= 0 else '#FF9999' for x in play_corr_without_self]
    bars = plt.barh(play_corr_without_self.index, play_corr_without_self, color=colors)

    # 为每个条形添加数值标签
    for bar in bars:
        width = bar.get_width()
        plt.text(
            width * 1.01,
            bar.get_y() + bar.get_height() / 2,
            f'{width:.2f}',
            va='center',
            fontproperties=font_prop
        )

    plt.title('各指标与播放量的相关系数', fontproperties=font_prop, fontsize=16)
    plt.xlabel('相关系数', fontproperties=font_prop, fontsize=12)
    plt.xlim(-0.1, 1.1)  # 设置x轴范围
    plt.axvline(x=0, color='gray', linestyle='--')  # 添加y轴参考线
    plt.grid(axis='x', linestyle='--', alpha=0.7)
    plt.tight_layout()

    # 保存图表
    output_file = f"{output_dir}/play_count_correlation.png"
    plt.savefig(output_file, dpi=300)
    plt.close()
    print(f"已保存条形图: {output_file}")

    # 5. 散点图矩阵（选择部分变量以避免图表过于复杂）
    print("\n绘制散点图矩阵...")
    # 选择最相关的几个变量
    selected_columns = ['播放量', '点赞数', '收藏数', '评论数', '弹幕数']

    # 创建散点图矩阵
    sns.set(style="ticks")
    scatter_matrix = sns.pairplot(
        data=df[selected_columns],
        diag_kind='kde',
        plot_kws={"alpha": 0.6, "s": 80}
    )

    # 单独设置散点图矩阵的字体
    for ax in scatter_matrix.axes.flat:
        ax.set_xlabel(ax.get_xlabel(), fontproperties=font_prop, fontsize=10)
        ax.set_ylabel(ax.get_ylabel(), fontproperties=font_prop, fontsize=10)

    plt.suptitle('B站视频数据指标散点图矩阵', fontproperties=font_prop, fontsize=16, y=1.02)

    # 保存图表
    output_file = f"{output_dir}/scatter_matrix.png"
    plt.savefig(output_file, dpi=300, bbox_inches='tight')
    plt.close()
    print(f"已保存散点图矩阵: {output_file}")

    # 6. 特定变量对之间的散点图（带回归线）
    print("\n绘制特定变量对之间的散点图...")

    # 定义要分析的变量对
    variable_pairs = [
        ('播放量', '点赞数'),
        ('播放量', '收藏数'),
        ('播放量', '弹幕数'),
        ('点赞数', '收藏数'),
        ('弹幕数', '评论数')
    ]

    # 为每对变量创建散点图
    for x_var, y_var in variable_pairs:
        plt.figure(figsize=(10, 8))

        # 计算皮尔逊相关系数和p值
        corr, p_value = pearsonr(df[x_var].values, df[y_var].values)

        # 绘制散点图
        plt.scatter(df[x_var], df[y_var], alpha=0.6, s=80, edgecolor='k')

        # 添加回归线
        z = np.polyfit(df[x_var], df[y_var], 1)
        p = np.poly1d(z)
        plt.plot(np.sort(df[x_var]), p(np.sort(df[x_var])), "r-", linewidth=2)

        plt.title(
            f'{x_var} 与 {y_var} 的关系\n相关系数: {corr:.2f}, P值: {p_value:.6f}',
            fontproperties=font_prop,
            fontsize=14
        )
        plt.xlabel(x_var, fontproperties=font_prop, fontsize=12)
        plt.ylabel(y_var, fontproperties=font_prop, fontsize=12)
        plt.grid(linestyle='--', alpha=0.7)
        plt.tight_layout()

        # 保存图表
        output_file = f"{output_dir}/{x_var}_vs_{y_var}_scatter.png"
        plt.savefig(output_file, dpi=300)
        plt.close()
        print(f"已保存散点图: {output_file}")

    # 7. 创建相关性分析的综合报告
    print("\n创建相关性分析的综合报告...")

    with open(f"{output_dir}/correlation_analysis_report.txt", "w", encoding="utf-8") as f:
        f.write("# B站视频数据指标相关性分析报告\n\n")

        f.write("## 基本统计信息\n\n")
        f.write(df[numeric_columns].describe().to_string())
        f.write("\n\n")

        f.write("## 相关系数矩阵\n\n")
        f.write(correlation_matrix.to_string())
        f.write("\n\n")

        f.write("## 与播放量相关性排序\n\n")
        f.write(play_correlations.to_string())
        f.write("\n\n")

        f.write("## 相关性分析总结\n\n")

        # 总结高相关性的变量对
        high_correlations = []
        for i in range(len(numeric_columns)):
            for j in range(i + 1, len(numeric_columns)):
                col1, col2 = numeric_columns[i], numeric_columns[j]
                corr_value = correlation_matrix.loc[col1, col2]
                if abs(corr_value) > 0.5:  # 相关系数绝对值大于0.5的视为高相关
                    high_correlations.append((col1, col2, corr_value))

        # 按相关系数绝对值排序
        high_correlations.sort(key=lambda x: abs(x[2]), reverse=True)

        f.write("### 高相关性变量对（|r| > 0.5）\n\n")
        for col1, col2, corr in high_correlations:
            corr_type = "正相关" if corr > 0 else "负相关"
            f.write(f"- {col1} 与 {col2}: {corr:.2f} ({corr_type})\n")

        f.write("\n### 关键发现\n\n")
        f.write(
            "1. 播放量与点赞数和收藏数之间存在较强的正相关关系，这符合预期，表明观看次数越多的视频通常获得的点赞和收藏也越多。\n")
        f.write("2. 弹幕数和评论数之间也存在较强的相关性，这表明观众在弹幕互动活跃的视频中，也更倾向于发表评论。\n")
        f.write("3. 转发数与收藏数的相关性也较高，说明用户喜欢分享他们认为有价值的内容。\n")
        f.write("4. 投币数与点赞数高度相关，表明用户的打赏行为与其对内容的喜爱程度密切相关。\n")

    print(f"已保存分析报告: {output_dir}/correlation_analysis_report.txt")

    print("\n相关性分析完成！")

except Exception as e:
    print(f"发生错误: {str(e)}")
    import traceback

    traceback.print_exc()